﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Janus.BaseEntitys
{
    [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
    public class ShowNameAttribute : System.Attribute
    {
        public string Nodes { get; set; }
        public string Names { get; set; }
        public ShowNameAttribute(string names, string nodes)
        {
            this.Nodes = nodes;
            this.Names = names;
        }

        public string ToName()
        {
            return Names;
        }

        public string ToNode()
        {
            return Nodes;
        }

        public override string ToString()
        {
            string result = string.Empty;
            if (Nodes != null) result = Nodes;
            if (Names != null)
            {
                if (!string.IsNullOrEmpty(result))
                {
                    result += " -> " + Names;
                }
                else
                {
                    result += Names;
                }
            }

            return result;
        }

    }

    public static class ShowNameExtensions
    {
        public static string GetName(
            this ICustomAttributeProvider provider)
        {
            var attributes = (ShowNameAttribute[])provider.GetCustomAttributes(
                typeof(ShowNameAttribute), false);
            return attributes.FirstOrDefault().Names;
        }

        public static string GetNodes(
            this ICustomAttributeProvider provider)
        {
            var attributes = (ShowNameAttribute[])provider.GetCustomAttributes(
                typeof(ShowNameAttribute), false);
            return attributes.FirstOrDefault().Nodes;
        }

        public static string GetAction(this ICustomAttributeProvider provider)
        {
            var attributes = (ShowNameAttribute[])provider.GetCustomAttributes(
                    typeof(ShowNameAttribute), false);
            return attributes.FirstOrDefault().ToString();
        }

        public static string ToName(this Enum value)
        {
            return value.GetType().GetField(value.ToString()).GetName();
        }

        public static string ToNodes(this Enum value)
        {
            return value.GetType().GetField(value.ToString()).GetNodes();
        }

        public static string ToAction(this Enum value)
        {
            return value.GetType().GetField(value.ToString()).GetAction();
        }

        public static Dictionary<Int32, String> ToDictionaryByName<TEnum>(this Enum value)
        {
            return Enum.GetValues(typeof(TEnum))
                .Cast<int>().OrderBy(c => c)
                .ToDictionary(e => e, e =>
                {
                    Enum enums = ToObject<TEnum>(e) as Enum;
                    return enums.ToName(); ;
                });
        }

        public static T ToObject<T>(int value)
        {
            var t = (T)Enum.ToObject(typeof(T), value);
            return t;
        }

        public static string ToAscII(this Enum value)
        {
            string result = "";
            int ascii = Convert.ToInt32(value);
            System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
            byte[] byteArray = new byte[] { (byte)ascii };
            result = asciiEncoding.GetString(byteArray);
            return result;
        }

        public static T ByAscII<T>(this Enum value, string ascii)
        {
            T t = default(T);
            System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
            int intAsciiCode = (int)asciiEncoding.GetBytes(ascii)[0];
            t = (T)Enum.ToObject(typeof(T), intAsciiCode);
            return t;
        }

        public static string ToNameByAscII(this Enum value, string ascii)
        {
            System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
            int intAsciiCode = (int)asciiEncoding.GetBytes(ascii)[0];
            var t = Enum.ToObject(value.GetType(), intAsciiCode);
            var result = value.GetType().GetField(t.ToString()).GetName();
            return result;
        }

        public static string ToNodesByAscII(this Enum value, string ascii)
        {
            System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
            int intAsciiCode = (int)asciiEncoding.GetBytes(ascii)[0];
            var t = Enum.ToObject(value.GetType(), intAsciiCode);
            var result = value.GetType().GetField(t.ToString()).GetNodes();
            return result;
        }

        public static string ToActionByAscII(this Enum value, string ascii)
        {
            System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
            int intAsciiCode = (int)asciiEncoding.GetBytes(ascii)[0];
            var t = Enum.ToObject(value.GetType(), intAsciiCode);
            var result = value.GetType().GetField(t.ToString()).GetAction();
            return result;
        }
    }
}
